package cn.xy.ymcc.service.impl;

import cn.xy.ymcc.domain.CourseType;
import cn.xy.ymcc.dto.MbxDto;
import cn.xy.ymcc.mapper.CourseTypeMapper;
import cn.xy.ymcc.result.JSONResult;
import cn.xy.ymcc.service.ICourseTypeService;
import cn.xy.ymcc.util.AssertUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author xy.cao
 * @since 2022-07-20
 */


//@Service
//public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
//    /**
//     * 无限极树
//     * 1、查出所有数据，
//     * 2、查顶级组成firstlist
//     * 3、其他所有不是顶级的都去找自己的上级，并加入上级的children
//     * @return
//     */
//    @Override
//    public List<CourseType> treeData() {
//        //查所有数据，不用注入mapper，此业务层自带的方法
//        List<CourseType> courseTypes = selectList(null);
//
//
//        HashMap<Long, CourseType> allTypes = new HashMap<>();
//        courseTypes.forEach(type->{
//            allTypes.put(type.getId(), type);
//        });
//
//
//        List<CourseType> firstlist = new ArrayList<>();
//        //调用for循环遍历集合的数据
//        for (CourseType type:courseTypes){
//            //判断是否为顶级
//            if(type.getPid() == null || type.getPid().intValue() == 0){
//                //为顶级，循环外部声明顶级集合，将判断后的值加入顶级集合，
//                firstlist.add(type);
//            }else {//不是顶级
//                allTypes.get(type.getPid()).getChildren().add(type);
//                //遍历数据
////                for (CourseType typeTemp:courseTypes){
////                    //根据pid和id的值判断是否为上下级
////                    if(typeTemp.getId().intValue() == type.getPid().intValue()){
////                        //为上下级
////                        typeTemp.getChildren().add(type);
////                    }
////
////
////                }
//
//
//            }
//
//        }
//
//        return firstlist;
//    }
//}

@Service
@Slf4j
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Autowired
    private CourseTypeMapper courseTypeMapper;

        /**
          * 无限极树
          * 1、查出所有数据，
          * 2、查顶级组成firstlist
          * 3、其他所有不是顶级的都去找自己的上级，并加入上级的children
          * @return
          */
    @Override
    @Cacheable(cacheNames="coursetype", key = "'tree'")
    public List<CourseType> treeData() {
        log.info("走数据库查询返回");
        List<CourseType> tree = tree();
        return tree;
    }




    /**
     * 备份
     * @return
     */
    public List<CourseType> treeData2() {
        //1.优先查询redis中有没有无限极树缓存
        String courseTypeTree = "coursetypetree";
        Object obj = redisTemplate.opsForValue().get(courseTypeTree);
        if(obj != null){
            log.info("走redis查询返回");
            //2.有，直接返回
            return (List<CourseType>) obj;
        }
        //3.没有，查询数据库，封装数据  存入redis
        log.info("走mysql查询返回");
        List<CourseType> tree = tree();
        redisTemplate.opsForValue().set(courseTypeTree,tree);
        return tree;
    }

    /**
     * 封装无限极树
     * @return
     */
    public List<CourseType> tree() {
        List<CourseType> courseTypes = selectList(null);
        HashMap<Long, CourseType> allTypes = new HashMap<>();
        courseTypes.forEach(type->{
            allTypes.put(type.getId(),type);
        });

        List<CourseType> firstList = new ArrayList<>();
        for (CourseType type:courseTypes){
            if(type.getPid() == null || type.getPid().intValue() == 0){
                firstList.add(type);
            }else{
                allTypes.get(type.getPid()).getChildren().add(type);
            }
        }
        return firstList;
    }

    @Override
    @CacheEvict(cacheNames="coursetype", key = "'tree'")
    public boolean insert(CourseType entity) {
        boolean insert = super.insert(entity);

        return insert;
    }

    @Override
    @CacheEvict(cacheNames="coursetype", key = "'tree'")
    public boolean updateById(CourseType entity) {
        boolean update = super.updateById(entity);

        return update;
    }

    @Override
    @CacheEvict(cacheNames="coursetype", key = "'tree'")
    public boolean deleteById(Serializable id) {
        boolean delete = super.deleteById(id);
        return delete;
    }

    /**
     * 面包屑
     * @param courseTypeId
     * @return
     */
    @Override
    public JSONResult crumbs(Long courseTypeId) {
        //创建数组
       List<MbxDto> returnList = new ArrayList<>();
       //参数校验
        AssertUtil.isNotNull(courseTypeId,"课程类型ID为空");
       //通过课程类型id查出课程类型数据
        CourseType courseType = courseTypeMapper.selectById(courseTypeId);
        //获取path，并且分割path得到多个id的集合
        String[] split = courseType.getPath().split("\\.");
        //根据id集合批量查询出对应的courseType数据
        List<CourseType> courseTypes = courseTypeMapper.selectBatchIds(Arrays.asList(split));
        //使用for循环遍历出每一个类型
        for (CourseType ct:courseTypes){
            //解决OwnerCourseType
            MbxDto mbxDto = new MbxDto();
            mbxDto.setOwnerCourseType(ct);
            //用得到的OwnerCourseType去查询同级的数据
            Wrapper<CourseType> tWrapper = new EntityWrapper<>();
            tWrapper.eq("pid",courseType.getPid()).ne("id",courseType.getId());
            List<CourseType> course = courseTypeMapper.selectList(tWrapper);
            mbxDto.setOtherCourseTypes(course);
            returnList.add(mbxDto);

        }

        return JSONResult.success(returnList);
    }


}

